package com.n5x.controller.front.shopping;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.n5x.common.base.JsonModel;
import com.n5x.common.base.ResponseCode;
import com.n5x.common.base.TokenModel;
import com.n5x.common.util.StringUtil;
import com.n5x.controller.BaseController;
import com.n5x.model.goods.GoodsInfo;
import com.n5x.model.shopping.ShoppingCart;
import com.n5x.model.shopping.ShoppingOrder;
import com.n5x.model.shopping.ShoppingOrderDetails;
import com.n5x.service.IGoodsService;
import com.n5x.service.IShoppingService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * 前台购物车接口
 * 需要用户token
 */
@Controller("order")
@RequestMapping("/front/shopping/order")
public class OrderController extends BaseController {

    @InitBinder("shoppingOrder")
    public void initBinderShoppingOrder(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("shoppingOrder.");
    }

    @InitBinder("userTransactionRecord")
    public void initBinderUserTransactionRecord(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("userTransactionRecord.");
    }

    @Autowired
    public HttpServletRequest request;

    @Autowired
    private IShoppingService iShoppingService;

    @Autowired
    private IGoodsService iGoodsService;


    @RequestMapping(value = "/validate")
    @ResponseBody
    public JsonModel validate(String params) {
        String id = request.getParameter("order_id");
        if (StringUtils.isBlank(id)) {
            return getResultError(ResponseCode.Common_ParamError, "订单ID不能为空:");
        }
        ShoppingOrder shoppingOrder = iShoppingService.findShoppingOrder(id);
        if (shoppingOrder == null) {
            return getResultError(ResponseCode.Common_ParamError, "订单不存在:" + id);
        }
        List<ShoppingOrderDetails> list = iShoppingService.findShoppingOrderDetails(id);
        for (ShoppingOrderDetails details : list) {
            String goodsId = details.getFkSourceId();
            if (StringUtils.isBlank(goodsId)) {
                return getResultError(ResponseCode.Common_ParamError, "商品不存在:" + id);
            }
            GoodsInfo goodsInfo = iGoodsService.findGoodsInfo(details.getFkSourceId());
            if (goodsInfo == null || goodsInfo.getDisable() == true) {
                return getResultError(ResponseCode.Common_ParamError, "商品不存在:" + id);
            }
            int goodsQty = goodsInfo.getQty();
            int detailsQty = details.getQty();
            if (goodsQty - detailsQty < 0) {
                return getResultError(ResponseCode.Common_ParamError, "商品库存不足:" + id);
            }
        }
        return getResult(id);
    }

    @RequestMapping(value = "/create")
    @ResponseBody
    public JsonModel create(String params) {
        try {
            String goodsArray = request.getParameter("goodsArray");
            String token = request.getParameter("token");
            Gson gs = new Gson();
            List<ShoppingCart> shoppingCarts = gs.fromJson(goodsArray, new TypeToken<List<ShoppingCart>>() {
            }.getType());
            TokenModel tokenModel = getTokenModelByToken(token);
            String userId = tokenModel.getUserId();
            logger.info("[生成商品订单]");
            List<String> nullList = new ArrayList<String>();
            List<String> disableList = new ArrayList<String>();
            List<ShoppingOrderDetails> orderDetails = new ArrayList<ShoppingOrderDetails>();
            for (ShoppingCart shoppingCart : shoppingCarts) {
                GoodsInfo goodsInfo = iGoodsService.findGoodsInfo(shoppingCart.getFkGoods());
                if (goodsInfo.getDisable() != null && goodsInfo.getDisable() == true) {
                    disableList.add(goodsInfo.getId());
                    continue;
                }
                if (goodsInfo.getQty() <= 0) {
                    nullList.add(goodsInfo.getId());
                    continue;
                }
                ShoppingOrderDetails shoppingOrderDetails = new ShoppingOrderDetails(goodsInfo, shoppingCart.getQty());
                orderDetails.add(shoppingOrderDetails);
            }
            if (CollectionUtils.isNotEmpty(nullList)) {
                JsonModel jsonModel = getResultError(ResponseCode.Common_DataNotFound, "商品库存为空");
                jsonModel.setData(nullList);
                return jsonModel;
            }
            if (CollectionUtils.isNotEmpty(disableList)) {
                JsonModel jsonModel = getResultError(ResponseCode.Common_DataNotFound, "商品已下架");
                jsonModel.setData(disableList);
                return jsonModel;
            }
            ShoppingOrder shoppingOder = iShoppingService.saveNewShoppingOrderByGoods(userId, orderDetails);
            if (shoppingOder == null) {
                return getResult(ResponseCode.Common_Fail, "订单创建失败");
            }
            return getResult(shoppingOder.getId());
        } catch (Exception e) {
            logger.error("[生成商品订单失败]e:{}", new Object[]{e.toString()});
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, e.toString());
        }
    }

    @RequestMapping(value = "/update")
    @ResponseBody
    public JsonModel updateShoppingOder() {
        try {
            String goodsArray = request.getParameter("shoppingOrder");
            String token = request.getParameter("token");
            Gson gs = new Gson();
            ShoppingOrder shoppingOrder = gs.fromJson(goodsArray, new TypeToken<ShoppingOrder>() {
            }.getType());
            TokenModel tokenModel = getTokenModelByToken(token);
            String userId = tokenModel.getUserId();
            logger.info("[生成商品订单]");
            ShoppingOrder myOrder = iShoppingService.findShoppingOrder(shoppingOrder.getId());
            if (myOrder == null || !userId.equals(myOrder.getFkUser()) || myOrder.getDisable().booleanValue() == Boolean.TRUE.booleanValue()) {
                return getResultError(ResponseCode.Common_DataNotFound, "订单不存在");
            }
            logger.info("[用户更新订单收货信息]shoppingOrder:{},userDiscountIds:{}", new Object[]{shoppingOrder});
            myOrder.setBooksingTime(shoppingOrder.getBooksingTime());
            myOrder.setErpressBoxAddress(shoppingOrder.getErpressBoxAddress());
            if (StringUtils.isNotBlank(shoppingOrder.getRemark())) {
                myOrder.setRemark(shoppingOrder.getRemark());
            }
            if (StringUtils.isNotBlank(shoppingOrder.getIsBalance())) {
                myOrder.setIsBalance(shoppingOrder.getIsBalance());
            }
            if (StringUtils.isNotBlank(shoppingOrder.getIsSendToHome())) {
                myOrder.setIsSendToHome(shoppingOrder.getIsSendToHome());
            }
            iShoppingService.saveShoppingOrder(myOrder, null);
            return getResult(myOrder.getId());
        } catch (Exception e) {
            logger.error("[生成商品订单失败]e:{}", new Object[]{e.toString()});
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, e.toString());
        }
    }

    @RequestMapping(value = "/pay")
    @ResponseBody
    public JsonModel pay() {
        try {
            String orderId = request.getParameter("orderId");
            //订单交易方式[0:现金,1:微信;2:支付宝;3:余额;4:优惠券]
            String method = request.getParameter("method");
            String money = request.getParameter("money");
            String transactionNumber = request.getParameter("transactionNumber");
            String token = request.getParameter("token");
            TokenModel tokenModel = getTokenModelByToken(token);
            String userId = tokenModel.getUserId();
            logger.info("[商品订单支付]orderId:{},method:{},money:{},transactionNumber:{},userId:{}", new Object[]{orderId, method, money, transactionNumber, userId});
            String redisKey = "pay_" + orderId;
            String payOrder = redisCache.getCacheObject(redisKey);
            if (StringUtils.isNotBlank(payOrder)) {
                return getResultError(ResponseCode.Common_ParamError, "表单重复提交");
            }
            if (StringUtils.isBlank(orderId)) {
                return getResultError(ResponseCode.Common_ParamError, "订单ID不能为空");
            }
            ShoppingOrder shoppingOrder = iShoppingService.findShoppingOrder(orderId);
            if (shoppingOrder == null) {
                return getResultError(ResponseCode.Common_ParamError, "订单不存在");
            }
            shoppingOrder.setTotalMoney(new BigDecimal(money));
            shoppingOrder.setTransactionMethod(method);
            shoppingOrder.setTransactionNumber(transactionNumber);
            Map<String, Object> result = iShoppingService.saveShoppingOrderByPay(shoppingOrder, userId);
            if (result != null && !result.isEmpty()) {
                String key = result.keySet().iterator().next();
                return getResultError(key, (String) result.get(key));
            }
            redisCache.setCacheObject(redisKey, orderId, 10);
            return getResult(shoppingOrder.getId());
        } catch (Exception e) {
            logger.error("[商品订单支付失败]e:{}", new Object[]{e.toString()});
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, e.toString());
        }
    }


    /**
     * 确认完成订单
     *
     * @return JsonModel
     */
    @RequestMapping(value = "/complete")
    @ResponseBody
    public JsonModel completeShoppingOrder() {
        try {
            String id = request.getParameter("id");
            if (StringUtils.isBlank(id)) {
                return getResultError(ResponseCode.Common_ParamError, "订单ID不能为空");
            }
            ShoppingOrder shoppingOrder = iShoppingService.findShoppingOrder(id);
            if (shoppingOrder == null) {
                return getResultError(ResponseCode.Common_ParamError, "订单不存在");
            }
            shoppingOrder.setCurrentState(ShoppingOrder.ShoppingState.完成.getState());
            shoppingOrder.setFinishTime(new Date());
            iShoppingService.saveShoppingOrder(shoppingOrder, null);
            return getResult(shoppingOrder.getId());
        } catch (Exception e) {
            logger.error("[商品订单完成失败]e:{}", new Object[]{e.toString()});
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, e.toString());
        }
    }

    /**
     * 查看物流详细列表
     *
     * @param token   用户token
     * @param orderId 订单ID
     * @return JsonModel
     */
    @RequestMapping(value = "/details")
    @ResponseBody
    public JsonModel shoppingOrderDetails(String token, @RequestParam(value = "orderId", required = false) String orderId) {
        try {
            TokenModel tokenModel = getTokenModelByToken(token);
            String userId = tokenModel.getUserId();
            if (StringUtils.isBlank(orderId)) {
                return getResultError(ResponseCode.Common_ParamError, "订单ID不能为空");
            }
            ShoppingOrder shoppingOrder = iShoppingService.findShoppingOrder(orderId);
            if (shoppingOrder == null) {
                return getResultError(ResponseCode.Common_ParamError, "订单不存在");
            }
            if (!userId.equals(shoppingOrder.getFkUser())) {
                return getResultError(ResponseCode.Common_ParamError, "用户与订单不匹配");
            }
            logger.info("[用户查看订单详细信息]orderId:{}", new Object[]{orderId});
            List<ShoppingOrderDetails> shoppingOrderDetails = iShoppingService.findShoppingOrderDetails(orderId);
            if (CollectionUtils.isEmpty(shoppingOrderDetails)) {
                return getResultError(ResponseCode.Common_DataNotFound, "订单详细列表为空");
            }
            return getResult(shoppingOrderDetails);
        } catch (Exception e) {
            logger.error("[查看订单详细列表失败]e:{}", new Object[]{e.toString()});
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, e.toString());
        }
    }

    /**
     * 订单详细信息
     *
     * @param token   用户token
     * @param orderId 订单ID
     * @return JsonModel
     */
    @RequestMapping(value = "/info")
    @ResponseBody
    public JsonModel shoppingOrderInfo(String token, @RequestParam(value = "orderId", required = false) String orderId) {
        try {
            TokenModel tokenModel = getTokenModelByToken(token);
            String userId = tokenModel.getUserId();
            if (StringUtils.isBlank(orderId)) {
                return getResultError(ResponseCode.Common_ParamError, "订单ID不能为空");
            }
            ShoppingOrder shoppingOrder = iShoppingService.findShoppingOrder(orderId);
            if (shoppingOrder == null) {
                return getResultError(ResponseCode.Common_DataNotFound, "订单不存在");
            }
            if (!userId.equals(shoppingOrder.getFkUser())) {
                return getResultError(ResponseCode.Common_ParamError, "用户与订单不匹配");
            }
            logger.info("[查询订单]orderId:{}，订单ID:", new Object[]{userId, orderId});
            return getResult(shoppingOrder);
        } catch (Exception e) {
            logger.error("[查询订单失败]e:{}", new Object[]{e.toString()});
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, e.toString());
        }
    }

    /**
     * 查看订单
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public JsonModel list() {
        try {
            String token = request.getParameter("token");
            String id = request.getParameter("id");
            String receiptCode = request.getParameter("receiptCode");
            String pageNum = request.getParameter("pageNum");
            String pageSize = request.getParameter("pageSize");
            String beginTime = request.getParameter("beginTime");
            String endTime = request.getParameter("endTime");
            String deliver = request.getParameter("deliver");
            String userName = request.getParameter("userName");
            String currentState = request.getParameter("currentState");
            String method = request.getParameter("method");
            //Gson gs = new Gson();
            TokenModel tokenModel = getTokenModelByToken(token);
            String userId = tokenModel.getUserId();
            logger.info("[查询用户订单]id:{},receiptCode:{},isFinish:{},createTimeBegin:{},createTimeEnd:{},finishTimeBegin:{},finishTimeEnd:{},pageNum:{},pageSize{}", new Object[]{id, receiptCode, pageNum, pageSize});
            Map pararm = new HashMap();
            pararm.put("id", id);
            pararm.put("receiptCode", receiptCode);
            pararm.put("userName", StringUtil.isBlank(userName) ? null : "%" + userName + "%");
            pararm.put("beginTime", beginTime);
            pararm.put("endTime", endTime);
            pararm.put("deliver", deliver);
            pararm.put("method", method);
            if (StringUtils.isNotBlank(currentState)) {
                String[] states = currentState.split(",");
                pararm.put("currentState", Arrays.asList(states));
            }
            int count = iShoppingService.countUserShopingOrder(pararm);
            Page page = null;
            if (pageNum != null && pageSize != null) {
                page = PageHelper.startPage(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
            }
            List<ShoppingOrder> list = iShoppingService.selectUserShopingOrder(pararm);
            if (null != page) {
                Long total = page.getTotal();
            }
            if (CollectionUtils.isEmpty(list)) {
                return getResult(ResponseCode.Common_DataNotFound, "找不到订单信息");
            }
            return getResult(list).setResult(String.valueOf(count));
        } catch (Exception e) {
            logger.error("[查找用户未完结订单失败]e:{}", new Object[]{e.toString()});
            e.printStackTrace();
            return getResultError(ResponseCode.Common_Error, e.toString());
        }
    }
}